home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
C/C++ Users Group Library 1996 July
/
C-C++ Users Group Library July 1996.iso
/
listings
/
v_10_01
/
cips1001.exe
/
EDGE.C
< prev
next >
Wrap
Text File
|
1991-04-20
|
18KB
|
743 lines
/***********************************************
*
* file d:\cips\edge.c
*
* Functions: This file contains
* detect_edges
* setup_masks
* get_edge_options
* perform_convolution
* quick_edge
* fix_edges
*
* Purpose:
* These functions implement several
* types of basic edge detection.
*
* External Calls:
* wtiff.c - does_not_exist
* round_off_image_size
* create_allocate_tiff_file
* write_array_into_tiff_image
* tiff.c - read_tiff_header
* rtiff.c - read_tiff_image
* numcvrt.c - get_integer
*
*
* Modifications:
* 27 January 1991 - created
*
*************************************************/
#include "d:\cips\cips.h"
short quick_mask[3][3] = {
{-1, 0, -1},
{ 0, 4, 0},
{-1, 0, -1} };
/***************************
*
* Directions for the masks
* 3 2 1
* 4 x 0
* 5 6 7
*
****************************/
/* masks for kirsch operator */
short kirsch_mask_0[3][3] = {
{ 5, 5, 5},
{-3, 0, -3},
{-3, -3, -3} };
short kirsch_mask_1[3][3] = {
{-3, 5, 5},
{-3, 0, 5},
{-3, -3, -3} };
short kirsch_mask_2[3][3] = {
{-3, -3, 5},
{-3, 0, 5},
{-3, -3, 5} };
short kirsch_mask_3[3][3] = {
{-3, -3, -3},
{-3, 0, 5},
{-3, 5, 5} };
short kirsch_mask_4[3][3] = {
{-3, -3, -3},
{-3, 0, -3},
{ 5, 5, 5} };
short kirsch_mask_5[3][3] = {
{-3, -3, -3},
{ 5, 0, -3},
{ 5, 5, -3} };
short kirsch_mask_6[3][3] = {
{ 5, -3, -3},
{ 5, 0, -3},
{ 5, -3, -3} };
short kirsch_mask_7[3][3] = {
{ 5, 5, -3},
{ 5, 0, -3},
{-3, -3, -3} };
/* masks for prewitt operator */
short prewitt_mask_0[3][3] = {
{ 1, 1, 1},
{ 1, -2, 1},
{-1, -1, -1} };
short prewitt_mask_1[3][3] = {
{ 1, 1, 1},
{ 1, -2, -1},
{ 1, -1, -1} };
short prewitt_mask_2[3][3] = {
{ 1, 1, -1},
{ 1, -2, -1},
{ 1, 1, -1} };
short prewitt_mask_3[3][3] = {
{ 1, -1, -1},
{ 1, -2, -1},
{ 1, 1, 1} };
short prewitt_mask_4[3][3] = {
{-1, -1, -1},
{ 1, -2, 1},
{ 1, 1, 1} };
short prewitt_mask_5[3][3] = {
{-1, -1, 1},
{-1, -2, 1},
{ 1, 1, 1} };
short prewitt_mask_6[3][3] = {
{-1, 1, 1},
{-1, -2, 1},
{-1, 1, 1} };
short prewitt_mask_7[3][3] = {
{ 1, 1, 1},
{-1, -2, 1},
{-1, -1, 1} };
/* masks for sobel operator */
short sobel_mask_0[3][3] = {
{ 1, 2, 1},
{ 0, 0, 0},
{-1, -2, -1} };
short sobel_mask_1[3][3] = {
{ 2, 1, 0},
{ 1, 0, -1},
{ 0, -1, -2} };
short sobel_mask_2[3][3] = {
{ 1, 0, -1},
{ 2, 0, -2},
{ 1, 0, -1} };
short sobel_mask_3[3][3] = {
{ 0, -1, -2},
{ 1, 0, -1},
{ 2, 1, 0} };
short sobel_mask_4[3][3] = {
{-1, -2, -1},
{ 0, 0, 0},
{ 1, 2, 1} };
short sobel_mask_5[3][3] = {
{-2, -1, 0},
{-1, 0, 1},
{ 0, 1, 2} };
short sobel_mask_6[3][3] = {
{-1, 0, 1},
{-2, 0, 2},
{-1, 0, 1} };
short sobel_mask_7[3][3] = {
{ 0, 1, 2},
{-1, 0, 1},
{-2, -1, 0} };
/**************************************************
*
* detect_edges(...
*
* This function detects edges in an area of one
* image and sends the result to another image
* on disk. It reads the input image from disk,
* calls a convolution function, and then writes
* the result out to disk. If needed, it
* allocates space on disk for the output image.
*
***************************************************/
detect_edges(in_name, out_name, the_image, out_image,
il, ie, ll, le, detect_type, threshold,
high)
char in_name[], out_name[];
int detect_type, high, il, ie,
ll, le, threshold;
short the_image[ROWS][COLS], out_image[ROWS][COLS];
{
int i, j, k, length, width;
struct tiff_header_struct image_header;
if(does_not_exist(out_name)){
read_tiff_header(in_name, &image_header);
round_off_image_size(&image_header,
&length, &width);
image_header.image_length = length*ROWS;
image_header.image_width = width*COLS;
create_allocate_tiff_file(out_name, &image_header,
out_image);
} /* ends if does_not_exist */
read_tiff_image(in_name, the_image, il, ie, ll, le);
read_tiff_header(in_name, &image_header);
perform_convolution(the_image, out_image,
detect_type, threshold,
&image_header, high);
fix_edges(out_image, 1);
write_array_into_tiff_image(out_name, out_image,
il, ie, ll, le);
} /* ends detect_edges */
/**********************************************************
*
* perform_convolution(...
*
* This function performs convolution between the input
* image and 8 3x3 masks. The result is placed in
* the out_image.
*
********************************************************/
perform_convolution(image, out_image,
detect_type, threshold,
image_header, high)
short image[ROWS][COLS],
out_image[ROWS][COLS];
int detect_type, high, threshold;
struct tiff_header_struct *image_header;
{
int a,
b,
i,
is_present,
j,
sum;
short mask_0[3][3],
mask_1[3][3],
mask_2[3][3],
mask_3[3][3],
mask_4[3][3],
mask_5[3][3],
mask_6[3][3],
mask_7[3][3],
max,
min,
new_hi,
new_low;
setup_masks(detect_type, mask_0, mask_1,
mask_2, mask_3, mask_4, mask_5,
mask_6, mask_7);
new_hi = 250;
new_low = 16;
if(image_header->bits_per_pixel == 4){
new_hi = 10;
new_low = 3;
}
min = 0;
max = 255;
if(image_header->bits_per_pixel == 4)
max = 16;
/* clear output image array */
for(i=0; i<ROWS; i++)
for(j=0; j<COLS; j++)
out_image[i][j] = 0;
printf("\n ");
for(i=1; i<ROWS-1; i++){
if( (i%10) == 0) printf("%3d", i);
for(j=1; j<COLS-1; j++){
/* Convolve for all 8 directions */
/* 0 direction */
sum = 0;
for(a=-1; a<2; a++){
for(b=-1; b<2; b++){
sum = sum + image[i+a][j+b] *
mask_0[a+1][b+1];
}
}
if(sum > max) sum = max;
if(sum < 0) sum = 0;
out_image[i][j] = sum;
/* 1 direction */
sum = 0;
for(a=-1; a<2; a++){
for(b=-1; b<2; b++){
sum = sum + image[i+a][j+b] * mask_1[a+1][b+1];
}
}
if(sum > max) sum = max;
if(sum < 0) sum = 0;
out_image[i][j] = sum;
/* 2 direction */
sum = 0;
for(a=-1; a<2; a++){
for(b=-1; b<2; b++){
sum = sum + image[i+a][j+b] * mask_2[a+1][b+1];
}
}
if(sum > max) sum = max;
if(sum < 0) sum = 0;
out_image[i][j] = sum;
/* 3 direction */
sum = 0;
for(a=-1; a<2; a++){
for(b